//
//  UIViewAdditions.m
//  Tint
//
//  Created by Kevin Wu on 2/22/12.
//  Copyright (c) 2012 Telligenty. All rights reserved.
//

#import "UIViewAdditions.h"
#import <QuartzCore/QuartzCore.h>
#import "TTCore.h"


@implementation UIView (Tint)


#pragma mark - Accessors

- (CGFloat)leftX {
    return self.frame.origin.x;
}
- (void)setLeftX:(CGFloat)leftX {
    [self setFrameIfNeeded:TTRectSetX(self.frame, leftX)];
}

- (CGFloat)centerX {
    return self.center.x;
}
- (void)setCenterX:(CGFloat)centerX {
    [self setCenterIfNeeded:TTPointSetX(self.center, centerX)];
}

- (CGFloat)rightX {
    return self.frame.origin.x + self.frame.size.width;
}
- (void)setRightX:(CGFloat)rightX {
    [self setFrameIfNeeded:TTRectSetX(self.frame, rightX-self.frame.size.width)];
}


- (CGFloat)topY {
    return self.frame.origin.y;
}
- (void)setTopY:(CGFloat)topY {
    [self setFrameIfNeeded:TTRectSetY(self.frame, topY)];
}

- (CGFloat)centerY {
    return self.center.y;
}
- (void)setCenterY:(CGFloat)centerY {
    [self setCenterIfNeeded:TTPointSetY(self.center, centerY)];
}

- (CGFloat)bottomY {
    return self.frame.origin.y + self.frame.size.height;
}
- (void)setBottomY:(CGFloat)bottomY {
    [self setFrameIfNeeded:TTRectSetY(self.frame, bottomY-self.frame.size.height)];
}



- (CGFloat)width {
    return self.frame.size.width;
}
- (void)setWidth:(CGFloat)width {
    [self setFrameIfNeeded:TTRectSetWidth(self.frame, width)];
}

- (CGFloat)height {
    return self.frame.size.height;
}
- (void)setHeight:(CGFloat)height {
    [self setFrameIfNeeded:TTRectSetHeight(self.frame, height)];
}



- (CGPoint)origin {
    return self.frame.origin;
}
- (void)setOrigin:(CGPoint)origin {
    [self setFrameIfNeeded:TTRectSetOrigin(self.frame, origin)];
}

- (CGSize)size {
    return self.frame.size;
}
- (void)setSize:(CGSize)size {
    [self setFrameIfNeeded:TTRectSetSize(self.frame, size)];
}



- (UIImage *)imageRepresentation {
	UIGraphicsBeginImageContext(self.bounds.size);
	[self.layer renderInContext:UIGraphicsGetCurrentContext()];
	UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	return image;
}

- (UIViewController *)viewController {
    for (UIView *next = self; next; next = next.superview) {
        UIResponder *nextResponder = [next nextResponder];
        if (TTIsInstance(nextResponder, [UIViewController class])) {
            return (UIViewController *)nextResponder;
        }
    }
    return nil;
}

- (NSArray *)superviews {
    if (self.superview) {
        NSMutableArray *superviews = [NSMutableArray array];
        UIView *view = self;
        while (view) {
            if (view.superview) {
                [superviews addObject:view.superview];
                view = self.superview;
            }
        }
        return [NSArray arrayWithArray:superviews];
    }
    return nil;
}



#pragma mark - Adding and removing subview

- (void)addCenteredSubview:(UIView *)subview {
    [self addSubview:subview];
    [subview moveToCenterOfSuperview];
}

- (void)removeAllSubviews {
    [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
}



#pragma mark - Placing

- (void)occupySupperView {
    if (self.superview) {
        self.frame = self.superview.bounds;
    }
}

- (void)moveToCenterOfSuperview {
    if (self.superview) {
        [self setCenterIfNeeded:CGPointMake(self.superview.width/2.0, self.superview.height/2.0)];
    }
}

- (void)moveToVerticalCenterOfSuperview {
    if (self.superview) {
        self.centerY = self.superview.height/2.0;
    }
}

- (void)moveToHorizontalCenterOfSuperview {
    if (self.superview) {
        self.centerX = self.superview.width/2.0;
    }
}

- (void)setFrameIfNeeded:(CGRect)frame {
    if (!TTIsRectEqualToRect(self.frame, frame)) {
        self.frame = frame;
    }
}

- (void)setCenterIfNeeded:(CGPoint)center {
    if (!TTIsPointEqualToPoint(self.center, center)) {
        self.center = center;
    }
}



#pragma mark - Finding views

- (UIView *)findFirstResponder {
    return TTFindFirstResponderInView(self);
}

- (NSArray *)subviewsWithClass:(Class)cls {
    NSMutableArray *views = [NSMutableArray array];
    for (UIView *v in self.subviews) {
        if ([v isKindOfClass:cls])
            [views addObject:v];
    }
    return views;
}

- (UIView *)descendantOrSelfWithClass:(Class)cls {
    if ([self isKindOfClass:cls])
        return self;
    
    for (UIView *child in self.subviews) {
        UIView *it = [child descendantOrSelfWithClass:cls];
        if (it)
            return it;
    }
    
    return nil;
}

- (UIView *)ancestorOrSelfWithClass:(Class)cls {
    if ([self isKindOfClass:cls]) {
        return self;
    } else if (self.superview) {
        return [self.superview ancestorOrSelfWithClass:cls];
    }
    return nil;
}



#pragma mark - Hierarchy

- (void)bringToFront {
	[self.superview bringSubviewToFront:self];
}

- (void)sendToBack {
	[self.superview sendSubviewToBack:self];
}

- (BOOL)isInFront {
	return ([self.superview.subviews lastObject] == self);
}

- (BOOL)isAtBack {
    NSArray *array = self.superview.subviews;
    if ([array count]>0) {
        return ([array objectAtIndex:0] == self);
    }
    return NO;
}



#pragma mark - Shadow

- (CAGradientLayer *)shadowAsInverse:(BOOL)inverse {
    CGFloat shadowHeight = 20.0;
    CGFloat inverseShadowHeight = 10.0;
    
	CAGradientLayer *newShadow = [[[CAGradientLayer alloc] init] autorelease];
	newShadow.frame = CGRectMake(0.0, 0.0, self.bounds.size.width, inverse ? inverseShadowHeight : shadowHeight);
    
	CGColorRef darkColor = [UIColor colorWithRed:0.0 
                                           green:0.0 
                                            blue:0.0 
                                           alpha:inverse ? (inverseShadowHeight / shadowHeight) * 0.6 : 0.6].CGColor;
	CGColorRef lightColor = [UIColor clearColor].CGColor;
    
	newShadow.colors = [NSArray arrayWithObjects:
                        (id)(inverse ? lightColor : darkColor), 
                        (id)(inverse ? darkColor : lightColor), nil];
	return newShadow;
}

- (void)dropShadowWithOpacity:(CGFloat)opacity {
    self.layer.masksToBounds = NO;
    self.layer.shadowOffset = CGSizeMake(0, 0);
    self.layer.shadowOpacity = opacity;
    self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;
}



#pragma mark - Debug

- (void)showBorderWithRandomColor {
    UIColor *color = [UIColor colorWithRed:((CGFloat)arc4random()) / (CGFloat)RAND_MAX 
                                     green:((CGFloat)arc4random()) / (CGFloat)RAND_MAX 
                                      blue:((CGFloat)arc4random()) / (CGFloat)RAND_MAX 
                                     alpha:1.0];
    [self showBorderWithColor:color];
}

- (void)showBorderWithColor:(UIColor *)color {
    self.layer.borderColor = color.CGColor;
	self.layer.borderWidth = 1.0;
}

- (void)dump {
    TTDPRINT(@"%@", NSStringFromCGRect(self.frame));
}

- (void)dumpSubviews {
    TTDumpSubviews(self, 0);
}

@end
